#预览编辑 markdown
# https://blog.csdn.net/winniezhang/article/details/146111815

import wx
import wx.html2  # HTML浏览器控件
import markdown  # Markdown解析模块
import pdfkit  # HTML转PDF模块
from PIL import Image
from io import BytesIO
import imgkit


def markdown_to_html_with_highlight(md_content):
    """将Markdown转换为HTML并添加代码高亮支持"""
    html_content = markdown.markdown(md_content, extensions=['fenced_code'])
    # 添加Highlight.js脚本和样式
    highlight_js = '''
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
    <script>hljs.highlightAll();</script>
    '''
    return f"{highlight_js}<body>{html_content}</body>"


class MarkdownApp(wx.Frame):
    def __init__(self):
        super().__init__(None, title="Markdown编辑工具", size=(1000, 700))
        self.InitUI()

    def InitUI(self):
        # 工具栏
        from wx._core import ToolBar
        toolbar:ToolBar = self.CreateToolBar(name="工具栏",style=wx.TB_TEXT)
        # 其中style参数用于定义wx.ToolBar样式 ，该参数支持以下这些效果：
        #
        # wx.TB_FLAT提供该工具栏平面效果
        # wx.TB_HORIZONTAL指定水平布局(默认)
        # wx.TB_VERTICAL指定垂直布局
        # wx.TB_DEFAULT_STYLE结合wxTB_FLAT和wxTB_HORIZONTAL
        # wx.TB_DOCKABLE使工具栏浮动和可停靠
        # wx.TB_NO_TOOLTIPS当鼠标悬停在工具栏不显示简短帮助工具提示
        # wx.TB_NOICONS指定工具栏按钮没有图标，默认它们是显示的
        # wx.TB_TEXT显示在工具栏按钮上的文本;
        # 默认情况下，只有图标显示


        toolbar.AddTool(
            wx.ID_SAVE,
            label="保存 Markdown",
            bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE) ,
            shortHelp="保存 Markdown",
             # longHelp = "保存 Markdown"
        )
        toolbar.AddTool(wx.ID_PREVIEW, "预览", wx.ArtProvider.GetBitmap(wx.ART_FIND),wx.NullBitmap, wx.ITEM_NORMAL,"预览")
        toolbar.AddTool(wx.ID_PRINT, "生成 PDF", wx.ArtProvider.GetBitmap(wx.ART_PRINT))
        toolbar.AddTool(wx.ID_SAVEAS, "保存为图片", wx.ArtProvider.GetBitmap(wx.ART_PASTE))
        toolbar.Realize()

        # 绑定工具栏按钮事件
        self.Bind(wx.EVT_TOOL, self.OnSaveMarkdown, id=wx.ID_SAVE)
        self.Bind(wx.EVT_TOOL, self.OnPreview, id=wx.ID_PREVIEW)
        self.Bind(wx.EVT_TOOL, self.OnGeneratePDF, id=wx.ID_PRINT)
        self.Bind(wx.EVT_TOOL, self.OnSaveImage, id=wx.ID_SAVEAS)

        # 布局
        panel = wx.Panel(self)
        vbox = wx.BoxSizer(wx.VERTICAL)

        self.memo = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
        self.browser = wx.html2.WebView.New(panel)

        vbox.Add(self.memo, 1, wx.EXPAND)
        vbox.Add(self.browser, 1, wx.EXPAND)

        panel.SetSizer(vbox)
        self.Show()

    def OnPreview(self, event):
        """预览Markdown内容为HTML"""
        md_content = self.memo.GetValue()
        html_content = markdown_to_html_with_highlight(md_content)
        self.browser.SetPage(html_content, "")

    def OnSaveMarkdown(self, event):
        """保存Markdown为.md文件"""
        with wx.FileDialog(self, "保存 Markdown", wildcard="Markdown 文件 (*.md)|*.md",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            with open(path, 'w', encoding='utf-8') as file:
                file.write(self.memo.GetValue())

    def OnGeneratePDF(self, event):
        """生成PDF文件"""
        md_content = self.memo.GetValue()
        html_content = markdown.markdown(md_content)
        with wx.FileDialog(self, "保存 PDF 文件", wildcard="PDF 文件 (*.pdf)|*.pdf",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            config = pdfkit.configuration(wkhtmltopdf='C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf.exe')
            pdfkit.from_string(html_content, path, configuration=config)

    def OnSaveImage(self, event):
        """保存HTML内容为JPEG图片"""
        md_content = self.memo.GetValue()
        html_content = markdown.markdown(md_content)
        with wx.FileDialog(self, "保存图片", wildcard="JPEG 文件 (*.jpeg)|*.jpeg",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_CANCEL:
                return
            path = dialog.GetPath()
            config = imgkit.config(wkhtmltoimage='C:/Program Files/wkhtmltopdf/bin/wkhtmltoimage.exe')
            img_data = imgkit.from_string(html_content, False, config=config)
            image = Image.open(BytesIO(img_data))
            image.save(path, format="JPEG")


if __name__ == "__main__":
    app = wx.App()
    MarkdownApp()
    app.MainLoop()
